home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000
/
Ham Radio 2000.iso
/
ham2000
/
morse
/
cw_rx
/
cw.c
next >
Wrap
C/C++ Source or Header
|
1994-10-02
|
9KB
|
276 lines
/***************************************************************
* CW.C *
* *
* OH3FG/KO4BC oct. 1, 1994 *
* slkhautaniem@tac.fi *
* *
***************************************************************/
#include <dos.h>
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
/* Printer port has 5 inputs: *
* pins 10, 11, 12, 13, and 15 */
#define MSK_15 0x08
#define MSK_13 0x10
#define MSK_12 0x20
#define MSK_10 0x40
#define MSK_11 0x80
/* Definitions to make code *
* more readable */
#define KEYUP (inportb(PRN + 1) & MSK)
#define KEYDOWN (!KEYUP)
#define UPDATE_UNIT unit = (unit + i)/2
#define SIDETONE_ON sound(400)
#define SIDETONE_OFF nosound()
#define OUT_WITH_KBD if (kbhit()) {SIDETONE_OFF; printf("%d\n",unit); exit(0);}
#define CNT (sizeof(chrs)/sizeof(chrs[0]))
typedef struct
{
char cw_image;
char asc;
}
MRK;
/* char cw-image sounds like */
MRK chrs[] =
{
{ 5,'A'}, /* 101 dit-dah */
{ 24,'B'}, /* 11000 dah-dit-dit-dit */
{ 26,'C'}, /* 11010 dah-dit-dah-dit */
{ 12,'D'}, /* 1100 dah-dit-dit */
{ 2,'E'}, /* 10 dit */
{ 18,'F'}, /* 10010 dit-dit-dah-dit */
{ 14,'G'}, /* 1110 dah-dah-dit */
{ 16,'H'}, /* 10000 dit-dit-dit-dit */
{ 4,'I'}, /* 100, dit-dit */
{ 23,'J'}, /* 1011 dit-dah-dah-dah */
{ 13,'K'}, /* 1101 dah-dit-dah */
{ 20,'L'}, /* 10100 dit-dah-dit-dit */
{ 7,'M'}, /* 111 dah-dah */
{ 6,'N'}, /* 110 dah-dit */
{ 15,'O'}, /* 1111 dah-dah-Σah */
{ 22,'P'}, /* 10110 dit-dah-dah-dit */
{ 29,'Q'}, /* 11101 dah-dah-dit-dah */
{ 10,'R'}, /* 1010 dit-dah-dit */
{ 8,'S'}, /* 1000 dit-dit-dit */
{ 3,'T'}, /* 11 dah */
{ 9,'U'}, /* 1001 dit-dit-dah */
{ 17,'V'}, /* 10001 dit-dit-dit-dah */
{ 11,'W'}, /* 1011 dit-dah-dah */
{ 25,'X'}, /* 11001 dah-dit-dit-dah */
{ 27,'Y'}, /* 11011 dah-dit-dah-dah */
{ 28,'Z'}, /* 11100 dah-dah-dit-dit */
{ 45,'Å'}, /* 101101 . - - . - */
{ 21,'Ä'}, /* 10101 . - . - */
{ 30,'Ö'}, /* 11110 - - - . */
{ 63,'0'}, /* 111111 - - - - - */
{ 47,'1'}, /* 101111 . - - - - */
{ 39,'2'}, /* 100111 . . - - - */
{ 35,'3'}, /* 100011 . . . - - */
{ 33,'4'}, /* 100001 . . . . - */
{ 32,'5'}, /* 100000 . . . . . */
{ 48,'6'}, /* 110000 - . . . . */
{ 56,'7'}, /* 111000 - - . . . */
{ 60,'8'}, /* 111100 - - - . . */
{ 62,'9'}, /* 111110 - - - - . */
{ 49,'='}, /* 110001 - . . . - */
{ 85,'.'}, /* 1010101 . - . - . - */
{115,','}, /* 1110011 - - . . - - */
{ 50,'/'}, /* 110010 - . . - . */
{ 76,'?'}, /* 1001100 . . - - . . */
{ 42,'+'}, /* 101010 . - . - . */
{ 54,'\n'}, /* 110110 - . - - . */
{ 34,'\b'}, /* 100010 . . . - . */
{ 69,'@'} /* 1000101 . . . - . - */
};
char usage[] =
" This program reads the MORSE -code given by cw-key\n"
" into a printer port of a PC -computer.\n"
" Following hookup works fine in authors computer:\n\n"
" printer port\n"
" pin 9 o──┐\n"
" │\n"
" █ 1k\n"
" │\n"
" pin 10,11,12,13, or 15 o──┼─────o\n"
" ╪ 1u cw-key\n"
" pin 25 o──┴─────o\n\n"
" Usage: CW pin# port# [unit_value]\n\n"
" If your key is connected between pins 12 and 25 at LPT1, you should command\n\n"
" CW 12 1 \n\n"
" The program exits by pressing any key while program is running.\n"
" At exit, it prints unit value you can give as third parameter next time\n"
" you run the program.\n"
" Oct. 2,1994 OH3FG/KO4BC";
int unit = 200; /* Default length of 'dit' *
* 200 suitable for fast AT's */
int space = 0;
int PRN,MSK;
char chr(void);
void neuvo(char *s);
main(int argc,char *argv[])
{
int c;
unsigned int cc;
unsigned int far *f;
/*
* Parse the command line parameters
*/
/* If pin number and *
* port not given *
* show help text *
* and exit */
if (argc < 3) neuvo(usage);
/* If optional unit *
* value given, *
* then use it. */
if ((c = atoi(argv[3])) != 0) unit = c;
/* Get the port number */
c = atoi(argv[2]);
f = MK_FP(0x40,6);
cc = *(f+c);
if (!cc) neuvo("No such port!");
PRN = cc;
/* Pin, where key *
* connected, is also *
* needed */
c = atoi(argv[1]);
SIDETONE_OFF;
switch (c)
{
case 10 : MSK = MSK_10; break;
case 11 : MSK = MSK_11; break;
case 12 : MSK = MSK_12; break;
case 13 : MSK = MSK_13; break;
case 15 : MSK = MSK_15; break;
default : neuvo("Pin, where key connected, must be 10, 11, 12, 13, or 15.");
}
/* Put voltage into *
* pullup resistor */
outportb(PRN,0x80);
/*
* Main loop of the program
*/
for (;;)
{
c=chr();
if (c=='\n') putch('\r'); /* If newline, */
if (c) putch(c); /* print CR first, */
}
}
/*
* chr() function does almost all the dirty work
*/
char chr()
{
int i, /* Duration of elements */
mrk, /* Cw-image */
c = 0; /* Character to return */
mrk = 1; /* Raise up the cw-image*
* begin flag. */
/* Wait 'till key down *
* or time of four *
* units. */
for (i=0;KEYUP && (i<4*unit);i++) OUT_WITH_KBD;
/* If pause longer than *
* four units then make *
* just one space. */
if ((i>=4*unit) && space)
{
space = 0; /* No more than 1 space */
return ' ';
}
/* Get cw-image of char *
* into mrk variable */
while KEYUP OUT_WITH_KBD;
for (;;) /* When the key goes down...*/
{
SIDETONE_ON; /* put on the tone */
mrk <<= 1; /* shift image left */
for (i=0;KEYDOWN;i++) OUT_WITH_KBD; /* wait until key up */
SIDETONE_OFF; /* Turn the tone off */
if (i>2*unit) /* If keydown time was *
* longer than two *
* units... */
{
mrk |= 1; /* raise LSB of image */
i /= 3; /* and divide time by 3*/
}
/* Else, leave i and *
* mrk variables alone */
/* The unit variable is *
* to be updated with i *
* variable - the key- *
* down time. */
UPDATE_UNIT;
/* If keyup time longer *
* than two units... */
for (i=0;KEYUP && (i<2*unit);i++) OUT_WITH_KBD;
if (i >= 2*unit) break; /* cw-image of char is *
* ready, so go for *
* printing it */
else UPDATE_UNIT; /* Else, i has length *
* for a 'dit', so *
* update unit. And go, *
* get next element. */
}
/* Search for a char of *
* this cw-image. */
for (i=0;i<CNT;i++)
{
if (chrs[i].cw_image == mrk)
{
c = chrs[i].asc; /* And return it. */
break;
}
/* Return 0 if *
* not found. */
}
/* Get ready for a *
* space between words. */
switch (c)
{
case '\n': /* No space after back- */
case '\b':break; /* space or newline */
default:space = 1;
}
return c;
}
void neuvo(char *s)
{
puts(s);
exit(1);
}